<?php

namespace app\common\service;

use app\admin\model\AppIpListen;
use app\admin\model\AppIpRoute;

class IpConfigService
{

    protected $modelConfig = null;

    protected $listPreviewRecord = [];

    public function __construct($model_config)
    {
        $this->modelConfig = $model_config;
    }

    public function buildPreviewMap()
    {
        $list_listen = AppIpListen::where('config_id', $this->modelConfig['id'])
            ->order('listen_ip', 'asc')
            ->order('listen_port', 'asc')
            ->where('status', 1)
            ->select();

        foreach ($list_listen as  $model_listen) {
            $list_route = AppIpRoute::where('listen_id', $model_listen['id'])
                ->order('route_ip', 'asc')
                ->order('route_port', 'asc')
                ->where('status', 1)
                ->select();

            foreach ($list_route as $model_route) {

                $record_item = [];

                $record_item['protocol'] = $model_listen['protocol'];

                $record_item['listen_ip'] = $model_listen['listen_ip'];

                $record_item['route_ip'] = $model_route['route_ip'];

                if ($model_listen['listen_type'] == 'port') {
                    $record_item['listen_port'] = $model_listen['listen_port'];
                    $this->buildRouteItems($record_item, $model_route);
                } else if ($model_listen['listen_type'] == 'range') {
                    $port_data = explode(':', $model_listen['listen_port']);
                    for ($port = $port_data[0]; $port <= $port_data[1]; $port++) {
                        $record_item['listen_port'] = $port;
                        $this->buildRouteItems($record_item, $model_route);
                    }
                } else if ($model_listen['listen_type'] == 'false_range') {

                    $port_data = explode(':', $model_listen['listen_port']);
                    $record_item['listen_port'] = $port_data[0];
                    $this->buildRouteItems($record_item, $model_route);
                }
            }
        }

        return $this->listPreviewRecord;
    }

    protected function buildRouteItems($record_item, $model_route)
    {
        if ($model_route['route_type'] == 'port') {
            $record_item['route_port'] = $model_route['route_port'];
            $this->listPreviewRecord[] = $record_item;
        } else if ($model_route['route_type'] == 'range') {
            $port_data = explode(':', $model_route['route_port']);
            for ($port = $port_data[0]; $port <= $port_data[1]; $port++) {
                $record_item['route_port'] = $port;
                $this->listPreviewRecord[] = $record_item;
            }
        } else if ($model_route['route_type'] == 'false_range') {
            $port_data = explode(':', $model_route['route_port']);
            $record_item['route_port'] = $port_data[0];
            $this->listPreviewRecord[] = $record_item;
        }
    }

    public function buildFalseRangeIptablesRules()
    {
        $list_listen_rules = [];

        $list_listen = AppIpListen::where('config_id', $this->modelConfig['id'])
            ->order('listen_ip', 'asc')
            ->order('listen_port', 'asc')
            ->where('status', 1)
            ->select();

        foreach ($list_listen as  $model_listen) {

            $list_route = AppIpRoute::where('listen_id', $model_listen['id'])
                ->order('route_ip', 'asc')
                ->order('route_port', 'asc')
                ->where('status', 1)
                ->select();

            foreach ($list_route as $model_route) {

                if ($model_route['route_type'] != 'false_range') {
                    continue;
                }

                $host_ip = $model_route['route_ip'];

                $port_data = explode(':', $model_route['route_port']);

                $start_port = $port_data[0] + 1;
                $end_port = $port_data[1];

                $record_item = [];
                $record_item['type'] = 'route';
                $record_item['title'] = $host_ip;

                $cmd = "iptables -t nat -I PREROUTING -p {$model_listen['protocol']} -d 127.0.0.1 --dport {$start_port}:{$end_port} -j DNAT --to 127.0.0.1:{$port_data[0]}";
                $record_item['cmd'] = $cmd;
                $list_listen_rules[] = $record_item;
            }

            if ($model_listen['listen_type'] != 'false_range') {
                continue;
            }
            $port_data = explode(':', $model_listen['listen_port']);

            $start_port = $port_data[0] + 1;
            $end_port = $port_data[1];

            $record_item = [];
            $record_item['type'] = 'listen';
            $record_item['title'] = '127.0.0.1';

            $cmd = "iptables -t nat -I PREROUTING -p {$model_listen['protocol']} -d 127.0.0.1 --dport {$start_port}:{$end_port} -j DNAT --to 127.0.0.1:{$port_data[0]}";
            $record_item['cmd'] = $cmd;

            $list_listen_rules[] = $record_item;
        }

        return $list_listen_rules;
    }
}
